//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <fcntl.h>

#include <aura.h>
#include <auraplus.h>
#include <aura_wchar.h>
#undef NULL
#include "private.h"

AURA_API AuraSystem_GetTime(
        /* [out] */ Aura_SystemTime * pTime)
{
    struct timeval tv;
    if(-1 == gettimeofday(&tv, NULL)){
        return AURA_E_FAIL;
    }

    pTime->seconds = (Aura_Int32)tv.tv_sec;
    pTime->microseconds = (Aura_Int32)tv.tv_usec;

    return AURA_NOERROR;
}

AURA_API AuraSystem_SetTime(
        /* [in] */ Aura_SystemTime * pTime)
{
    struct timeval tv;
    tv.tv_sec = (long)pTime->seconds;
    tv.tv_usec = (long)pTime->microseconds;

    if(-1 == settimeofday(&tv, NULL)){
        return AURA_E_FAIL;
    }

    return AURA_NOERROR;
}

AURA_API AuraSystem_QueryPerformanceCounter(
        /* [out] */Aura_Int64 * pCounter)
{
    FixMe("Not implemented yet.");
    return AURA_E_NOT_IMPLEMENTED;
}

AURA_API AuraSystem_QueryPerformanceFrequency(
        /* [out] */Aura_Int64 * pFrequency)
{
    FixMe("Not implemented yet.");
    return AURA_E_NOT_IMPLEMENTED;
}

AURA_API AuraSystem_GetElapsedTime(
        /* [out] */ Aura_Millisecond32 * pTime)
{
    FixMe("Not implemented yet.");
    return AURA_E_NOT_IMPLEMENTED;
}

AURA_API AuraSystem_GetIdleTime(
        /* [out] */ Aura_Millisecond32 * pTime)
{
    FixMe("Not implemented yet.");
    return AURA_E_NOT_IMPLEMENTED;
}

AURA_API AuraSystem_GetMemorySizes(
        /* [out] */ Aura_Int32 * pTotalPhysicalMemorySize,
        /* [out] */ Aura_Int32 * pAvailablePhysicalMemorySize)
{
    FILE *iFd;
    char *pLine = NULL;
    ssize_t iReadSize = 0;
    size_t iLen = 0;
    int i;

    Aura_UInt32 uTotalMem = 0;
    Aura_UInt32 uUsedMem = 0;
    Aura_UInt32 uFreeMem = 0;
    Aura_UInt32 uSharedMem = 0;
    Aura_UInt32 uBuffersMem = 0;
    Aura_UInt32 uCachedMem = 0;

    iFd = fopen("/proc/meminfo", "r");
    if(NULL == iFd){
        PERROR("Error: Get Memory Size failed! errno%d. \
        file:%s. line:%d. \n",
        errno, __FILE__, __LINE__);
        return AURA_E_INVALID_OPERATION;
    }

    for(i = 0; i < 2; i++){
        if(NULL != pLine){
            free(pLine);
            iLen = 0;
        }
        iReadSize = getline(&pLine, &iLen, iFd);
        if(-1 == iReadSize){
            PERROR("Error: Get Memory Size failed! errno%d. \
            file:%s. line:%d. \n",
            errno, __FILE__, __LINE__);
            fclose(iFd);
            return AURA_E_INVALID_OPERATION;
        }
    }

    sscanf(pLine, "Mem:  %d %d %d %d %d %d\n",
            &uTotalMem,
            &uUsedMem,
            &uFreeMem,
            &uSharedMem,
            &uBuffersMem,
            &uCachedMem);

    if(NULL != pTotalPhysicalMemorySize){
        *pTotalPhysicalMemorySize = (Aura_Int32)uTotalMem;
    }

    if(NULL != pAvailablePhysicalMemorySize){
        *pAvailablePhysicalMemorySize = (Aura_Int32)uFreeMem;
    }


    if(NULL != pLine){
        free(pLine);
    }
    fclose(iFd);

    return AURA_NOERROR;
}

AURA_API AuraSystem_ErrorPrint(
        /* [in] */ Aura_PWChar wstr)
{
    assert(wstr && wstr[0] != 0);

    int len=Aura_Wcslen(wstr);
    wchar_t *lwstr = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));
    if(!lwstr) return AURA_E_OUT_OF_MEMORY;
    Aura_PWchar_to_Pwchar_t(wstr,lwstr);
    wprintf(L"%S", lwstr);
    free (lwstr);
    return AURA_NOERROR;
}

